package br.unicamp.integralization;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import br.unicamp.integralization.dp.PotaSolver;
import br.unicamp.integralization.dto.Allocation;
import br.unicamp.integralization.dto.History;
import br.unicamp.integralization.dto.Subject;
import br.unicamp.integralization.dto.SubjectGroup;
import br.unicamp.integralization.request.RequestDTO;
import br.unicamp.integralization.request.RequestStatusEnum;
import br.unicamp.integralization.request.RequestTask;

import com.google.gson.Gson;

public class AllocationActivity extends Activity {

	public static final String HISTORY_JSON = "br.unicamp.integralization.HISTORY_JSON";

	private History history;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_allocation);

		String json = getIntent().getExtras().getString(HISTORY_JSON);
		history = (History) new Gson().fromJson(json, History.class);

		new ValidateAllocationRequestTask(this, history).execute();
	}

	private void setListViewHeightBasedOnChildren(ListView listView) {
		ListAdapter listAdapter = listView.getAdapter();
		if (listAdapter == null) {
			// pre-condition
			return;
		}

		int totalHeight = 0;
		for (int i = 0; i < listAdapter.getCount(); i++) {
			View listItem = listAdapter.getView(i, null, listView);
			listItem.measure(0, 0);
			totalHeight += listItem.getMeasuredHeight()
					+ listItem.getPaddingTop() + listItem.getPaddingBottom();
		}

		ViewGroup.LayoutParams params = listView.getLayoutParams();
		params.height = totalHeight
				+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
		listView.setLayoutParams(params);
	}

	private List<Triple> buildTripleList(List<Subject> subjectList) {
		List<Triple> tripleList = new ArrayList<Triple>();
		int length = subjectList.size();
		for (int i = 0; i < length - 2; i += 3) {
			tripleList.add(new Triple(subjectList.get(i).getAbbreviation(),
					subjectList.get(i + 1).getAbbreviation(), subjectList.get(
							i + 2).getAbbreviation()));
		}
		if (length % 3 == 1) {
			// adiciona ultimo elemento
			tripleList.add(new Triple(subjectList.get(length - 1)
					.getAbbreviation(), "", ""));
		} else if (length % 3 == 2) {
			// adiciona 2 ultimos
			tripleList.add(new Triple(subjectList.get(length - 2)
					.getAbbreviation(), subjectList.get(length - 1)
					.getAbbreviation(), ""));
		}
		return tripleList;
	}

	private class SubjectTripleArrayAdapter extends ArrayAdapter<Triple> {

		public SubjectTripleArrayAdapter(Context context, int resource,
				List<Triple> tripleList) {
			super(context, resource, tripleList);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = LayoutInflater.from(getContext()).inflate(
					R.layout.subject_list_item, parent, false);
			Triple triple = getItem(position);

			// first subject
			((TextView) view.findViewById(R.id.text_view_left))
					.setText(triple.left);

			// second subject
			((TextView) view.findViewById(R.id.text_view_center))
					.setText(triple.center);

			// third subject
			((TextView) view.findViewById(R.id.text_view_right))
					.setText(triple.right);

			return view;
		}

	}

	private class Triple {
		public String left;
		public String center;
		public String right;

		public Triple(String left, String center, String right) {
			this.left = left;
			this.center = center;
			this.right = right;
		}

	}

	private class ValidateAllocationRequestTask extends RequestTask {

		public static final String URL_VALIDATE_ALLOCATION = "http://www.students.ic.unicamp.br/~ra104864/mc857/servidorDac/rest/validar_alocacao";

		private Activity mActivity;
		private ProgressDialog pd;
		private History history;
		private List<Subject> historySubjects;

		public ValidateAllocationRequestTask(Activity mActivity, History history) {
			super();
			this.mActivity = mActivity;
			this.pd = ProgressDialog.show(mActivity, "",
					mActivity.getString(R.string.calculating_integralization),
					true);
			this.history = history;
			this.historySubjects = new ArrayList<Subject>();
		}

		@Override
		protected RequestDTO doInBackground(String... urls) {
			String params = "";
			try {
				Allocation bestAllocation = PotaSolver.execute(this.history
						.clone());

				if (bestAllocation == null) {
					return new RequestDTO(
							RequestStatusEnum.ERROR.code(),
							"O aluno não cumpre os créditos necessários para a integralização completa.",
							"");
				}

				history.setAllocation(bestAllocation.clone());

				// formatHistorySubjectsType(bestAllocation);

				// elimina grupo de extra-curriculares
				bestAllocation.getElectiveGroups().remove(
						bestAllocation.getElectiveGroups().size() - 1);
				params = "ra=" + history.getStudent().getRa() + "&alocacao="
						+ new Gson().toJson(bestAllocation);

			} catch (Exception e) {
				e.printStackTrace();
			}
			return super.doInBackground(URL_VALIDATE_ALLOCATION,
					RequestTask.METHOD_POST, params);
		}

		@SuppressWarnings("unused")
		private void formatHistorySubjectsType(Allocation bestAllocation) {
			// formata historico com tipo de atribuicao de cada disciplina
			// obrigatorias
			for (Subject s : bestAllocation.getMandatorySubjects()
					.getSubjects()) {
				this.historySubjects.add(new Subject(
						s.getAbbreviation() + " +", s.getCredits()));
			}
			// eletivas
			List<SubjectGroup> electiveGroups = bestAllocation
					.getElectiveGroups();
			for (int i = 0; i < electiveGroups.size() - 1; i++) {
				for (Subject s : electiveGroups.get(i).getSubjects()) {
					this.historySubjects.add(new Subject(s.getAbbreviation()
							+ " *", s.getCredits()));
				}
			}
			for (Subject s : electiveGroups.get(electiveGroups.size() - 1)
					.getSubjects()) {
				this.historySubjects.add(new Subject(
						s.getAbbreviation() + " X", s.getCredits()));
			}
		}

		@Override
		protected void onPostExecute(RequestDTO result) {
			if (result.getStatus() == RequestStatusEnum.OK.code()) {

				// dados do aluno
				((TextView) findViewById(R.id.text_view_student))
						.setText(history.getStudent().getName());
				((TextView) findViewById(R.id.text_view_academic_registry))
						.setText(history.getStudent().getRa());
				((TextView) findViewById(R.id.text_view_course))
						.setText(history.getCourse());
				// modalidade
				if (history.getModality() == null
						|| history.getModality().equals("")) {
					findViewById(R.id.display_modality)
							.setVisibility(View.GONE);
					findViewById(R.id.text_view_modality).setVisibility(
							View.GONE);
				} else {
					((TextView) findViewById(R.id.text_view_modality))
							.setText(history.getModality());
				}
				// opcao
				if (history.getOption() == null
						|| history.getOption().equals("")) {
					findViewById(R.id.display_option).setVisibility(View.GONE);
					findViewById(R.id.text_view_option)
							.setVisibility(View.GONE);
				} else {
					((TextView) findViewById(R.id.text_view_option))
							.setText(history.getOption());
				}

				// historico do aluno
				ListView historySubjectsListView = (ListView) findViewById(R.id.history_subjects);
				if (historySubjects == null || historySubjects.isEmpty()) {
					findViewById(R.id.layout_history_details).setVisibility(
							View.GONE);
				} else {
					List<Triple> historyTripleList = buildTripleList(historySubjects);
					historySubjectsListView
							.setAdapter(new SubjectTripleArrayAdapter(
									getApplicationContext(),
									R.layout.subject_list_item,
									historyTripleList));
				}

				// obrigatorias faltantes
				ListView mandatorySubjectsListView = (ListView) findViewById(R.id.mandatory_subjects);
				List<Subject> mandatorySubjectList = history.getAllocation()
						.getMandatorySubjects().getSubjects();
				if (mandatorySubjectList == null
						|| mandatorySubjectList.isEmpty()) {
					findViewById(R.id.layout_mandatory_todo).setVisibility(
							View.GONE);
				} else {
					List<Triple> mandatoryTripleList = buildTripleList(mandatorySubjectList);
					mandatorySubjectsListView
							.setAdapter(new SubjectTripleArrayAdapter(
									getApplicationContext(),
									R.layout.subject_list_item,
									mandatoryTripleList));
				}

				// grupos de eletivas
				LinearLayout layoutAllocation = (LinearLayout) findViewById(R.id.layout_allocation);
				boolean atLeastOne = false;
				int i = 1;
				for (SubjectGroup subjectGroup : history.getAllocation()
						.getElectiveGroups()) {
					if (subjectGroup.getCredits() > 0) {
						// so' exibe se ainda faltar creditos desse grupo
						atLeastOne = true;
						View child = getLayoutInflater().inflate(
								R.layout.elective_group_list_item, null);
						((TextView) child
								.findViewById(R.id.display_elective_group_todo))
								.setText(String
										.format(getString(R.string.obtain_x_credits_in),
												i++, subjectGroup.getCredits()));

						// disciplinas do grupo
						ListView electiveSubjects = (ListView) child
								.findViewById(R.id.elective_subjects);
						List<Triple> electiveTripleList = buildTripleList(subjectGroup
								.getSubjects());
						electiveSubjects
								.setAdapter(new SubjectTripleArrayAdapter(
										getApplicationContext(),
										R.layout.subject_list_item,
										electiveTripleList));
						layoutAllocation.addView(child);
						setListViewHeightBasedOnChildren(electiveSubjects);
					}
				}
				// se nao houver nenhum grupo de eletivas
				if (!atLeastOne) {
					// esconde display
					findViewById(R.id.layout_elective_todo).setVisibility(
							View.GONE);
				}

				setListViewHeightBasedOnChildren(historySubjectsListView);
				setListViewHeightBasedOnChildren(mandatorySubjectsListView);
				pd.dismiss();
			} else {
				pd.dismiss();
				String message = "Ocorreu um erro. Verifique sua conexão, o RA digitado, e tente novamente";
				if (result.getStatus() == RequestStatusEnum.ERROR.code()
						&& result.getMsg() != null
						&& result.getMsg().compareTo("") != 0) {
					message = result.getMsg();
				}
				Toast.makeText(mActivity, message, Toast.LENGTH_LONG).show();
				Intent intent = new Intent(mActivity, RARequestActivity.class);
				intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				startActivity(intent);
				finish();
			}
		}

	}
}
